/***
* ==++==
*
* Copyright (c) Microsoft Corporation.  All rights reserved.
*
* ==--==
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* xxwin32.h - Implementation Details of the Win32 layer of messaging -- this header is safe for inclusion in
*               public APIs
*
* Functions and types for interoperating with Win32 from modern C++ 
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/

#pragma once

#include <exception>
#include <string>
#include "xxpublic.h"

namespace actors
{
namespace details
{
namespace win32
{
    struct _reentrant_lock;

    /// <summary>
    /// This is a general-purpose reentrant critical section
    /// </summary>
    /// <remarks>
    /// This is a wrapper around a windows CRITICAL_SECTION
    /// </remarks>
    class reentrant_lock
    {
    public:
        _ASYNCRTIMP reentrant_lock();
        _ASYNCRTIMP ~reentrant_lock();

        _ASYNCRTIMP void lock();
        _ASYNCRTIMP void unlock();

        class scoped_lock
        {
        public:
            scoped_lock(reentrant_lock& lock) : m_lock(lock) { m_lock.lock(); }

            ~scoped_lock() { m_lock.unlock(); }

        private:
            scoped_lock();
            scoped_lock(const scoped_lock&);
            scoped_lock& operator=(const scoped_lock&);

            reentrant_lock& m_lock;
        };
    
    private:
        // don't allow copying
        reentrant_lock& operator=(const reentrant_lock& other);
        reentrant_lock(const reentrant_lock& other);

        _reentrant_lock *m_lock;
    };

    _ASYNCRTIMP unsigned int interlocked_comp_exchange(volatile unsigned int *dst, unsigned int value, unsigned int comp);

} // namespace actors::details::win32
}
}